//Tue Mar  8 12:32:42 CST 2011
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
/**
DIDN'T PASS.
Idea: sort them, then add all the symtry word, and count them.
2nd, all those two words, which are symmytry.
3rd, for those single palindrome words, if they have odd number of that word, remove one.
4th, choose the biggest value of single palindrome word, if it exists, then add it to the total value.
*/
using namespace std;

class PalindromeGame
{
public:

    int getMaximum(vector <string> front, vector <int> back)
    {
        vector<pair<int, string> > v;
        vector<pair<int, string> > v2;
        map<string, int> mp;
        for (int i = 0; i < front.size(); i++)
        {
            v.push_back(make_pair(-back[i], front[i]));
            v2.push_back(make_pair(back[i], front[i]));
            mp[front[i]] = 0;
        }

        sort(v.begin(), v.end());
        int count = 0;
        int i = 0;
        while (i < v.size())
        {
            if (checkPalindrome(v[i].second))
            {
                count += v[i].first;
                mp[v[i].second]++;
                v.erase(v.begin() + i);
                continue;
            }
            bool flag = true;
            for (int j = i + 1; j < v.size(); j++)
            {
                if (checkPair(v[i].second, v[j].second))
                {
                    count += v[i].first + v[j].first;
                    v.erase(v.begin() + i);
                    v.erase(v.begin() + j);
                    flag = false;
                    break;
                }
            }
            if (flag)
                i++;
        }
        int mmax = 0;
        count = -count;
        for (int i = 0; i < v2.size(); i++)
        {
            if (mp[v2[i].second] % 2 == 1)
            {
                mp[v2[i].second]--;
                count -= v2[i].first;
                mmax = max(mmax, v2[i].first);
            }
        }
        return count + mmax;
    }

    bool checkPair(string a, string b)
    {
        if (checkPalindrome(a + b)) return true;
        if (checkPalindrome(b + a)) return true;
        return false;
    }

    bool checkPalindrome(string a)
    {
        int sz = a.size();
        for (int i = 0, j = sz - 1; i <= j; i++, j--)
        {
            if (a[i] != a[j])
                return false;
        }
        return true;
    }
};

//{{"aaaaaaaaaaaa", "nopalindrome", "steponnopets", "emordnilapon", "aaaaaaaaaaaa", "steponnopets", "nopalindrome", "steponnopets", "nopalindrome", "bbbbbbbbbbbb", "cannotbeused", "cannotbeused", "steponnopets", "aaaaaaaaaaaa", "nopalindrome", "aaaaaaaaaaaa", "nopalindrome", "emordnilapon", "steponnopets", "nopalindrome"}}
//{{4096, 131072, 64, 262144, 512, 1024, 65536, 2048, 32768, 1, 524288, 16384, 32, 4, 16, 2, 8, 128, 8192, 256}}
